<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>DockerFly</title>
</head>
<link rel="shortcut icon" type="image/x-icon" href="img/favicon.ico"/>
<link rel="stylesheet" href="css/uikit/uikit.css"/>
<script src="js/common/jquery.min.js"></script>
<script src="js/common/vue.min.js"></script>
<script src="js/common/uikit.js"></script>
<script src="js/common/xterm.js"></script>
<link rel="stylesheet" href="css/main.css"/>
<link rel="stylesheet" href="css/xterm.css"/>

<script lang="javascript" src="js/utils.js"></script>
<script lang="javascript">
    doImport("org.voovan.docker.command.Container.CmdContainerList")
    doImport("org.voovan.docker.command.Container.CmdContainerLogs")
    doImport("org.voovan.docker.command.Container.CmdContainerTop")
    doImport("org.voovan.docker.command.Container.CmdContainerTop")
    doImport("org.voovan.docker.command.Container.CmdContainerStats")
    doImport("org.voovan.docker.command.Exec.CmdExecCreate")
    doImport("org.voovan.docker.command.Exec.CmdExecStart")

    function init() {
        viewerVue = new Vue({
            el: '#viewerApp',
            data: {
                logInfo :{
                    terminal: null,
                    timeStamp: null,
                    interval: 1000,
                    loop: null,
                    cmdObject: null
                },
                stats : null,
                processes: null,
                execInfo: {
                    cmd: "sh",
                    terminal: null,
                    interval : 150,
                    loop : null,
                    cmdObject: null
                }
            },
            computed: {
                viewContainer: function () {
                    try {

                        var containerId = getQueryString("id");
                        var cmdContainerList = new CmdContainerList()
                        cmdContainerList.connect()
                        cmdContainerList.all(true);
                        cmdContainerList.id([containerId])
                        var viewContainer = cmdContainerList.send();
                        cmdContainerList.close();
                        cmdContainerList.release();
                        if(viewContainer.length == 1){
                            document.title = delFirestChar(viewContainer[0].names[0]) +
                                " [" +viewContainer[0].state+"] DockerFly";
                            return viewContainer[0];
                        }else {
                            return null;
                        }
                    } catch (e) {
                        alertError(e)
                    }
                }
            },
            methods:{
                logView: function(){
                    try{
                        if(this.logInfo.loop !=null){
                            alert("Log view is running.")
                            return;
                        }

                        var cmdContainerLogs = new CmdContainerLogs(this.viewContainer.id);
                        cmdContainerLogs.connect(60);
                        this.logInfo.cmdObject = cmdContainerLogs;

                        //控制启动的时间,避免重复日志的输出
                        while(true){
                            var millisSecond = new Date().getUTCMilliseconds();
                            if(millisSecond>0 && millisSecond<400){
                                break;
                            }
                        }

                        //构造终端面板
                        if(viewerVue.logInfo.terminal==null){
                            viewerVue.logInfo.terminal = terminal("logPanel")
                        }

                        //循环输出日志
                        this.logInfo.loop = setInterval(
                            function() {
                                try {
                                    if(viewerVue.logInfo.timeStamp==null) {
                                        cmdContainerLogs.tail("15");
                                    }else{
                                        cmdContainerLogs.tail("all");
                                        cmdContainerLogs.since(viewerVue.logInfo.timeStamp);
                                    }
                                    viewerVue.logInfo.timeStamp = parseInt(currentTimeMills() / 1000);
                                    var logData = cmdContainerLogs.send();
                                    logData = logData.replaceAll("\r", "")
                                    logData = logData.replaceAll("\n", "\u0000")
                                    logData = logData.replaceAll("\u0000", "\r\n");
                                    viewerVue.logInfo.terminal.write(logData);
                                }catch(e){
                                    viewerVue.logStop();
                                    alertError(e)
                                }
                            }, this.logInfo.interval
                        );
                    } catch (e) {
                        alertError(e);
                    }
                },

                logStop: function(){
                    clearInterval(this.logInfo.loop)
                    this.logInfo.loop = null;
                    try {
                        if (this.logInfo.cmdObject != null) {
                            this.logInfo.cmdObject.close();
                            this.logInfo.cmdObject.release();
                        }
                    }catch(e){
                    console.log(e.message)
                    }
                    this.logInfo.cmdObject = null;
                },

                logClear: function(){
                    viewerVue.logInfo.timeStamp = null;
                    viewerVue.logInfo.terminal.clear();
                },

                processView: function(){
                    try{
                        var cmdContainerTop = new CmdContainerTop(this.viewContainer.id)
                        cmdContainerTop.connect();
                        this.processes = cmdContainerTop.send();
                        cmdContainerTop.close();
                        cmdContainerTop.release();
                    } catch (e) {
                        alertError(e);
                    }
                },
                statsView: function(){
                    try{
                        var cmdContainerStats = new CmdContainerStats(this.viewContainer.id)
                        cmdContainerStats.connect();
                        var statsData = cmdContainerStats.send();
                        cmdContainerStats.close();
                        cmdContainerStats.release();

                        this.stats = {};
                        this.stats.cpu = (statsData.cpuUsage/statsData.cpuTotal*100).toFixed(2);
                        this.stats.memUsage  = (statsData.memoryUsage/1024/1024).toFixed(2);
                        this.stats.memeLimit = Math.ceil(statsData.memoryMaxLimit/1024/1024);
                        this.stats.ioRead  = (statsData.ioRead/1000).toFixed(2);
                        this.stats.ioSend  = (statsData.ioWrite/1000).toFixed(2);
                        this.stats.ioTotal = (statsData.ioTotal/1000).toFixed(2);
                        for(var etherName in statsData.network) {
                            var etherStats = ether = eval("statsData.network."+etherName);
                            eval("this.stats.network={}");
                            eval("this.stats.network."+etherName+"={}");
                            eval("this.stats.network."+etherName+".netRx = (etherStats.netRxBytes / 1000).toFixed(0)");
                            eval("this.stats.network."+etherName+".netTx = (etherStats.netTxBytes / 1000).toFixed(0)");
                        }
                    } catch (e) {
                        alertError(e);
                    }
                },

                execute: function(){
                    try {
                        if(this.execInfo.loop !=null){
                            alert("Executor is running.")
                            return;
                        }

                        var cmdExecCreate = new CmdExecCreate(this.viewContainer.id);
                        cmdExecCreate.connect();
                        cmdExecCreate.cmd(this.execInfo.cmd.split(" "));
                        cmdExecCreate.tty(true);
                        cmdExecCreate.attachStdin(true);
                        var execId = cmdExecCreate.send();
                        cmdExecCreate.close();
                        cmdExecCreate.release();

                        var cmdExecStart = new CmdExecStart(eval("k="+execId).Id);
                        cmdExecStart.connect(60);
                        this.execInfo.cmdObject = cmdExecStart;
                        cmdExecStart.tty(true);
                        cmdExecStart.send();

                        //构造终端面板
                        if(this.execInfo.terminal==null){
                            this.execInfo.terminal = terminal("execPanel")

                            //绑定键盘输入动作
                            this.execInfo.terminal.on("data", function(data){
                                if(data.length==1) {
                                    if(viewerVue.execInfo.cmdObject!=null) {
                                        viewerVue.execInfo.cmdObject.send(data);
                                    }
                                }
                            })
                        }

                        //循环输出日志
                        this.execInfo.loop = setInterval(
                            function () {
                                var execData = null;
                                try {
                                    var execData = cmdExecStart.loadStream();
                                    if (execData != null) {
                                        viewerVue.execInfo.terminal.write(execData);
                                    } else {
                                        viewerVue.execStop();
                                    }
                                }catch (e){
                                    viewerVue.execStop();
                                    alertError(e)
                                }
                            }, this.execInfo.interval);
                    } catch (e) {
                        clearInterval(this.execInfo.loop );
                        alertError(e);
                    }
                },

                execStop: function(){
                    clearInterval(this.execInfo.loop)
                    this.execInfo.loop = null;
                        try {
                            if (this.execInfo.cmdObject != null) {
                                this.execInfo.cmdObject.close();
                                this.execInfo.cmdObject.release();
                            }
                        }catch(e){}
                    this.execInfo.cmdObject = null;
                },

                execClear: function(){
                    viewerVue.execInfo.terminal.clear();
                },
            }
        });

        if(viewerVue.viewContainer.state=="running") {
            viewerVue.processView();
            viewerVue.statsView();
        }
    }
</script>
<body onload="init()" class="frameBody" style="margin-right: 35px">
<div id="viewerApp" class="uk-grid" style="display: none" v-show="this.viewContainer!=null">
    <div class="uk-width-6-6">
        <div class="uk-panel"></div>
        <h3 class="uk-text-middle"><span class="uk-text-danger uk-text-bold uk-text-large">
            {{viewContainer.names[0]|delFirestChar}}</span> [ {{viewContainer.state}} ]
        </h3>
        <ul class="uk-tab" data-uk-switcher="{connect:'#Viewers'}">
            <li><a href="#">Performance</a></li>
            <li><a href="#">Execute</a></li>
            <li><a href="#">Log</a></li>
        </ul>
        <div id="Viewers" class="uk-switcher" style="padding-top:15px">
            <!-- 性能信息 -->
            <div>

                <div>
                    <table class="uk-table uk-table-condensed uk-overflow-container uk-panel-box">
                        <caption>
                            <div class="uk-grid" style="margin-bottom: 3px">
                                <div class="uk-width-5-6">Status</div>
                                <div class="uk-width-1-6 uk-text-center">
                                    <a class="uk-button uk-button-small uk-button-primary" @click="statsView">Refresh</a>
                                </div>
                            </div>
                        </caption>
                        <thead>
                        <th class="uk-width-1-4 uk-text-center">CPU</th>
                        <th class="uk-width-1-4 uk-text-center">Memory (Usage/Limit)</th>
                        <th class="uk-width-1-4 uk-text-center">IO (Read/Send/Total)</th>
                        <th class="uk-width-1-4 uk-text-center">Net (Rx/Tx)</th>
                        </thead>
                        <tbody>
                        <tr v-if="stats!=null">
                            <td class="uk-text-center">
                                <span class="uk-text-danger">{{stats.cpu}}%</span>
                            </td>
                            <td class="uk-text-center">
                                <span class="uk-text-primary">{{stats.memUsage}} MB </span> /
                                <span class="uk-text-success">{{stats.memeLimit}} MB</span>
                            </td>
                            <td class="uk-text-center">
                                <span class="uk-text-primary">{{stats.ioRead}} KB </span>/
                                <span class="uk-text-warning">{{stats.ioSend}} KB </span>/
                                <span class="uk-text-success">{{stats.ioTotal}} KB</span>
                            </td>
                            <td class="uk-text-center">
                                <div v-for="(etherStats, etherName) in stats.network">
                                    <span class=""><code>{{etherName}}</code></span>
                                    <span class="uk-text-primary">{{etherStats.netRx}} KB </span>/
                                    <span class="uk-text-success">{{etherStats.netTx}} KB </span>
                                </div>
                            </td>
                        </tr>
                        </tbody>
                    </table>
                    <hr/>
                    <table class="uk-table uk-table-condensed uk-overflow-container uk-panel-box">
                        <caption>
                            <div class="uk-grid"  style="margin-bottom: 3px">
                                <div class="uk-width-5-6">Container process</div>
                                <div class="uk-width-1-6 uk-text-center">
                                    <a class="uk-button uk-button-small uk-button-primary" @click="processView">Refresh</a>
                                </div>
                            </div>
                        </caption>
                        <thead>
                        <th class="uk-width-1-10 uk-text-center">NO.</th>
                        <th class="uk-width-1-10">PID</th>
                        <th class="uk-width-1-10">User</th>
                        <th class="uk-width-1-10">Time</th>
                        <th class="uk-width-6-10">Command</th>
                        </thead>
                        <tbody>
                            <tr v-for="(proecess,index) in processes">
                                <td class="uk-text-center uk-text-middle uk-text-small">{{index}}</td>
                                <td class="uk-text-primary">{{proecess.pid}}</td>
                                <td class="uk-text-warning">{{proecess.user}}</td>
                                <td class="uk-text-success">{{proecess.time}}</td>
                                <td><code>{{proecess.command}}</code></td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <!-- 执行命令  v-html="execInfo.data" class="terminal" style="height:400px; overflow-y: scroll;"-->
            <div>
                <div class="uk-grid uk-form">
                    <div class="uk-width-4-6">
                        <input class="uk-form-width-large" type="text"
                               placeholder="Command will be execute in contianer" v-model="execInfo.cmd"/>
                    </div>
                    <div class="uk-width-2-6 uk-text-right">
                        <a class="uk-button uk-button-small uk-button-primary"
                           @click="execute" v-show="execInfo.loop==null">Run</a>
                        <a class="uk-button uk-button-small uk-button-danger"
                           @click="execStop" v-show="execInfo.loop!=null">Stop</a>
                        <a class="uk-button uk-button-small uk-button-success" @click="execClear">Clear</a>
                    </div>
                </div>
                <hr>
                <div id="execPanel" class="terminal"></div>
            </div>
            <!-- 日志 v-html="logInfo.data" class="terminal"  style="height:400px; overflow-y: scroll;"-->
            <div>
                <div class="uk-grid uk-form">
                    <div class="uk-width-4-6" style="line-height: 30px">
                        <code>{{viewContainer==null?"":viewContainer.command}}</code>
                    </div>
                    <div class="uk-width-2-6 uk-text-right">
                        <a class="uk-button uk-button-small uk-button-primary"
                           @click="logView" v-show="logInfo.loop==null">Fetch</a>
                        <a class="uk-button uk-button-small uk-button-danger"
                           @click="logStop" v-show="logInfo.loop!=null">Stop</a>
                        <a class="uk-button uk-button-small uk-button-success" @click="logClear">Clear</a>
                    </div>
                </div>
                <hr>
                <div id="logPanel" class="terminal"></div>
            </div>
        </div>
    </div>
    <div class="uk-width-6-6">
        <div style="min-height:40px; margin-bottom:10px" class="uk-text-center">
            <div><img height="27" width="120" src="img/logo.png"/></div>
            <div>CopyRight <span class="uk-icon-copyright"></span> Voovan Vsetful</div>
            <div>Powered by Voovan open source framework.</div>
            <div></div>
        </div>
    </div>
</div>

</body>
</html>